package com.huawei.esdk.oa.device.exchange.common;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;

import org.apache.log4j.Logger;
import com.huawei.esdk.platform.common.utils.StringUtils;
import microsoft.exchange.webservices.data.ExchangeCredentials;
import microsoft.exchange.webservices.data.ExchangeService;
import microsoft.exchange.webservices.data.ExchangeVersion;
import microsoft.exchange.webservices.data.WebCredentials;

public class ExchangeServiceFactory
{
	private static String url; 
	private static String userName; 
	private static String pwd;
	private static String version;
	private static String deviceName;
	
    private static ExchangeService service;
    
    private static final Logger LOGGER = Logger.getLogger(ExchangeServiceFactory.class);
    
    public static ExchangeService getService()
    {
        if (null == service)
        {
            initService(url, userName, pwd, version);
        }
        
        return service;
    }
    
    public static void initService(String url, String userName, 
    		String pwd, String version)
    {
    	if(null == url || null == userName || null == pwd || null == version)
    	{
    		return;
    	}
    	
        if(!checkEmail(userName))
        {
            String errInfo = "Exchange Device userName incorrect, should be an email addresss";
            LOGGER.error(errInfo);
            return;
        }
        
    	ExchangeServiceFactory.url = url;
    	ExchangeServiceFactory.userName = userName;
    	ExchangeServiceFactory.pwd = pwd;
    	ExchangeServiceFactory.version = version;
    	
    	ExchangeVersion exchangeVersion = getExchangeVersionFromStr(version);
        service = new ExchangeService(exchangeVersion);
        
        try
        {
            ExchangeCredentials credentials =
                new WebCredentials(userName, pwd);
            
            service.setCredentials(credentials);

            service.setUrl(new URI(url));
            
            if(version.equals("Exchange2007_SP1"))
            {
                enableExchange2007CompatibilityMode(service);
            }
        }
        catch (NoSuchMethodException e)
        {
            LOGGER.error("exchange initService error", e);
        }
        catch (SecurityException e)
        {
            LOGGER.error("exchange initService error", e);
        }
        catch (IllegalAccessException e)
        {
            LOGGER.error("exchange initService error", e);
        }
        catch (IllegalArgumentException e)
        {
            LOGGER.error("exchange initService error", e);
        }
        catch (InvocationTargetException e)
        {
            LOGGER.error("exchange initService error", e);
        }
        catch (URISyntaxException e)
        {
            LOGGER.error("exchange initService error", e);
        }
              
    }
    
    private static void enableExchange2007CompatibilityMode(ExchangeService service) 
        throws NoSuchMethodException, SecurityException,
        IllegalAccessException, IllegalArgumentException, InvocationTargetException
    {
        Method method = microsoft.exchange.webservices.data.ExchangeService
            .class.getDeclaredMethod("setExchange2007CompatibilityMode", boolean.class);
        method.setAccessible(true);
        method.invoke(service, true);
    }
    
    private static ExchangeVersion getExchangeVersionFromStr(String version)
    {
    	ExchangeVersion exchangeVersion = null;
    	try
    	{
    		exchangeVersion = ExchangeVersion.valueOf(ExchangeVersion.class, version);
    	}
    	catch(IllegalArgumentException e)
    	{
    		exchangeVersion = ExchangeVersion.Exchange2010;
    		LOGGER.error("this exchange version not existed and set default value to Exchange2010");
    	}
    		
    	return exchangeVersion;		
    }

    public static boolean checkEmail(String email)
    {
        boolean flag = false;
        if(StringUtils.isNotEmpty(email) && -1 != email.indexOf("@"))
        {
            return true;
        }
        return flag;
    }
    
    public static String getDeviceName()
    {
        return deviceName;
    }

    public static void setDeviceName(String deviceName)
    {
        ExchangeServiceFactory.deviceName = deviceName;
    }

    public static String getUrl()
    {
        return url;
    }

    public static void setUrl(String url)
    {
        ExchangeServiceFactory.url = url;
    }

    public static String getUserName()
    {
        return userName;
    }

    public static void setUserName(String userName)
    {
        ExchangeServiceFactory.userName = userName;
    }

    public static String getPwd()
    {
        return pwd;
    }

    public static void setPwd(String pwd)
    {
        ExchangeServiceFactory.pwd = pwd;
    }

    public static String getVersion()
    {
        return version;
    }

    public static void setVersion(String version)
    {
        ExchangeServiceFactory.version = version;
    }
}
